package tiktok

import (
	"cid-media-api/internal/adcore"
	"context"
	"sync"
)

type TikTokAdapter struct {
	sdk *TikTokSDK
}

func NewTikTokAdapter() *TikTokAdapter {
	return &TikTokAdapter{sdk: NewTikTokSDK()}
}

func (a *TikTokAdapter) BatchCreate(ctx context.Context, req adcore.BatchRequest) (adcore.BatchResult, error) {
	result := adcore.BatchResult{}
	var wg sync.WaitGroup
	errChan := make(chan error, 1)
	mu := sync.Mutex{}

	// 步骤1：创建所有Campaign
	for _, c := range req.Campaigns {
		wg.Add(1)
		go func(c adcore.CampaignParams) {
			defer wg.Done()

			campaignID, err := a.sdk.CreateCampaign(c.Name)
			if err != nil {
				select {
				case errChan <- &adcore.AdError{"tiktok", "create_campaign", err.Error()}:
				default:
				}
				return
			}

			mu.Lock()
			result.CampaignIDs = append(result.CampaignIDs, campaignID)
			mu.Unlock()
		}(c)
	}
	wg.Wait()

	// 检查错误
	select {
	case err := <-errChan:
		return result, err
	default:
	}

	// 步骤2：创建AdGroup
	for _, ag := range req.AdGroups {
		wg.Add(1)
		go func(ag adcore.AdGroupParams) {
			defer wg.Done()

			if len(result.CampaignIDs) == 0 {
				select {
				case errChan <- &adcore.AdError{"tiktok", "create_adgroup", "no campaign available"}:
				default:
				}
				return
			}
			ag.CampaignID = result.CampaignIDs[0] // 关联第一个Campaign

			adGroupID, err := a.sdk.CreateAdGroup(ag.CampaignID)
			if err != nil {
				select {
				case errChan <- &adcore.AdError{"tiktok", "create_adgroup", err.Error()}:
				default:
				}
				return
			}

			mu.Lock()
			result.AdGroupIDs = append(result.AdGroupIDs, adGroupID)
			mu.Unlock()
		}(ag)
	}
	wg.Wait()

	// 步骤3：创建Ad
	for _, ad := range req.Ads {
		wg.Add(1)
		go func(ad adcore.AdParams) {
			defer wg.Done()

			if len(result.AdGroupIDs) == 0 {
				select {
				case errChan <- &adcore.AdError{"tiktok", "create_ad", "no adgroup available"}:
				default:
				}
				return
			}

			adID, err := a.sdk.CreateAd()
			if err != nil {
				select {
				case errChan <- &adcore.AdError{"tiktok", "create_ad", err.Error()}:
				default:
				}
				return
			}

			mu.Lock()
			result.AdIDs = append(result.AdIDs, adID)
			mu.Unlock()
		}(ad)
	}
	wg.Wait()

	return result, nil
}
